package com.uottawa.clickerapp.controller;

import com.uottawa.clickerapp.domain.*;
import com.uottawa.clickerapp.dao.impl.*;


import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.uottawa.clickerapp.service.ClickerAppService;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;

@Controller
public class ClickerAppMainController {
	
	@Resource(name="clickerAppService")
	private ClickerAppService clickerAppService;
	
	@RequestMapping(value= {"/", "/admin"}, method = RequestMethod.GET)
	public String home(){
		return "home";
	}
	@RequestMapping(value="/create", method = RequestMethod.GET)
	public String createQuestion(){
		return "createQuestion";
	}
	@RequestMapping(value="/select", method = RequestMethod.GET)
	public String selectSession(){
		return "selectSession";
	}
	@RequestMapping(value="/display", method = RequestMethod.GET)
	public String displayQuestion(){
		return "displayQuestion";
	}
	@RequestMapping(value="/report", method = RequestMethod.GET)
	public String displayReports(){
		return "displayReports";
	}
	
	@RequestMapping(value="/graph", method = RequestMethod.GET)
	public String displayGraph(){
		return "graph";
	}
	
	@RequestMapping(value="/graph2", method = RequestMethod.GET)
	public String displayGraph2(){
		return "graph2";
	}
	
	@RequestMapping(value="/graph3", method = RequestMethod.GET)
	public String displayGraph3(){
		return "graph3";
	}
	
	@RequestMapping(value="/json/newsession/{keyword}/{password}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public QuestionSession createQuestionSession(@PathVariable String keyword, @PathVariable String password){
		QuestionSession qs = new QuestionSession();
		qs.setKeyword(keyword);
		qs.setPassword(password);
		SQLDBHelper.store(qs);
		return qs;
	}
	
	@RequestMapping(value="/xml/newsession/{keyword}/{password}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public QuestionSession createQuestionSessionXml(@PathVariable String keyword, @PathVariable String password){
		return this.createQuestionSession(keyword, password);
	}
	
	@RequestMapping(value="/json/newquestion/{keyword}/{password}", method = RequestMethod.POST, produces = "application/json")
	@ResponseBody
	public Boolean addQuestion(@PathVariable String keyword, 
			@PathVariable String password
			,@RequestBody Question question){
		Long questionSessionID = SQLDBHelper.getQuestionSessions(keyword).get(0).getID();
		question.setQuestionSessionID(questionSessionID);
		if (checkUser(questionSessionID, password)){
			SQLDBHelper.store(question);
		return true;
		} else return false;
	}
	
	@RequestMapping(value="/xml/newquestion/{keyword}/{password}", method = RequestMethod.POST, produces = "application/xml")
	@ResponseBody
	public boolean addQuestionXml(@PathVariable String keyword, 
			@PathVariable String password
			,@RequestBody Question question){
		return this.addQuestion(keyword, password, question);
	}
	
	@RequestMapping(value="/json/editquestion/{questionSessionID}/{password}/", method = RequestMethod.POST, produces = "application/json")
	@ResponseBody
	public Question editQuestion(long questionSessionID, String password, Question question){
		if (checkUser(questionSessionID, password)){
			SQLDBHelper.store(question);
			return question;
		} else return null;
	}
	
	@RequestMapping(value="/xml/editquestion/{questionSessionID}/{password}/", method = RequestMethod.POST, produces = "application/xml")
	@ResponseBody
	public Question editQuestionXml(long questionSessionID, String password, Question question){
		return this.editQuestion(questionSessionID, password, question);
	}
	
	@RequestMapping(value="/json/enablequestion/{keyword}/{password}/{questionID}/{enable}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public String enableQuestion(@PathVariable String keyword, @PathVariable String password, @PathVariable Long questionID, @PathVariable Boolean enable){
		
		QuestionSession qs = SQLDBHelper.getQuestionSessions(keyword).get(0);
		if (qs == null) return "Invalid Question Session";
			
		Long questionSessionID = qs.getID();
		
		if (checkUser(questionSessionID, password)){
			Question q = new Question();
			q.setID(questionID);
			SQLDBHelper.fetch(q);
			q.setEnabled(enable);
			if ( SQLDBHelper.enable(q, enable) ) return "Success";
			else return "Failed";
		}
		return "Unauthorized";
	}
	
	@RequestMapping(value="/xml/enablequestion/{keyword}/{password}/{questionID}/{enable}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public String enableQuestionXml(@PathVariable String keyword, @PathVariable String password, @PathVariable Long questionID, @PathVariable Boolean enable){
		return enableQuestion(keyword, password, questionID, enable);
	}
	
	@RequestMapping(value="/json/removequestion/{keyword}/{password}/{questionID}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public String removeQuestion(@PathVariable String keyword, @PathVariable String password, @PathVariable Long questionID){
		
		QuestionSession qs = SQLDBHelper.getQuestionSessions(keyword).get(0);
		if (qs == null) return "Invalid Question Session";
			
		Long questionSessionID = qs.getID();
		
		if (checkUser(questionSessionID, password)){
			Question q = new Question();
			q.setID(questionID);
			q.fetch();
			if ( SQLDBHelper.delete(q) ){
				SQLDBHelper.deleteAnswers(q.getID() );
				return "Success";
			}
			else return "Failed";
			
		}
		return "Unauthorized";
	}
	
	@RequestMapping(value="/xml/removequestion/{keyword}/{password}/{questionID}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public String removeQuestionXml(@PathVariable String keyword, @PathVariable String password, @PathVariable Long questionID){
		return this.removeQuestion(keyword, password, questionID);
	}
	
	@RequestMapping(value="/json/submit/{questionID}/{answerID}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public String submitPoll(@PathVariable Long questionID, @PathVariable Long answerID, HttpSession session){
		Question q = new Question();
		q.setID(questionID);
		SQLDBHelper.fetch(q);
		
		if (!q.isEnabled()) return "Question is not Enabled";
		
		if (SQLDBHelper.store(questionID, answerID, Long.valueOf(session.getId().hashCode()), q.canMultipleSubmit()) )
			return "Answer Submitted";
		else return "Failed";
	}
	
	@RequestMapping(value="/xml/submit/{questionID}/{answerID}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public String submitPollXml(@PathVariable Long questionID, @PathVariable Long answerID, HttpSession session){
		return this.submitPoll(questionID, answerID, session);
	}
	
	@RequestMapping(value="/json/getquestions/{keyword}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public QuestionSession getQuestions(@PathVariable String keyword){
		
		return SQLDBHelper.getQuestionSessions(keyword).get(0);
	}
	
	@RequestMapping(value="/xml/getquestions/{keyword}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public QuestionSession getQuestionsXml(@PathVariable String keyword){
		return this.getQuestions(keyword);
	}
	
	@RequestMapping(value="/json/getResults/{questionID}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public List<Long> getResults(@PathVariable Long questionID){
		List<Long> results = new ArrayList<Long>();
		List<Answer> answers = SQLDBHelper.getAnswers(questionID);
		for (int i = 0; i < answers.size(); i++) {
			results.add(SQLDBHelper.getPolls(answers.get(i).getID()));
		}
		return results;
	}
	
	@RequestMapping(value="/xml/getResults/{questionID}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public List<Long> getResultsXml(@PathVariable Long questionID){
		return this.getResults(questionID);
	}
	
	@RequestMapping(value="/json/getAnswers/{questionID}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public List<Answer> getAnswers(@PathVariable Long questionID){
		return SQLDBHelper.getAnswers(questionID);
	}
	
	@RequestMapping(value="/xml/getAnswers/{questionID}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public List<Answer> getAnswersXml(@PathVariable Long questionID){
		return this.getAnswers(questionID);
	}
	
	@RequestMapping(value="/json/searchSessions/{keyword}", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public List<QuestionSession> searchSessions(String keyword){
		return SQLDBHelper.getQuestionSessions(keyword);
	}
	
	@RequestMapping(value="/xml/searchSessions/{keyword}", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public List<QuestionSession> searchSessionsXml(String keyword){
		return this.searchSessions(keyword);
	}
	
	@RequestMapping(value="/json/recentsessions", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public List<String> getRecentSessions(HttpSession session){
		List<String> result = SQLDBHelper.getNonEmptySessionNames();
		return result;
	}
	
	@RequestMapping(value="/json/admin/recentsessions", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public List<String> getRecentSessionsForAdmin(HttpSession session){
		List<String> result = SQLDBHelper.getSessionNames();
		return result;
	}
	
	@RequestMapping(value="/json/newsessioID", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public String getSessionID(HttpSession session){
		return session.getId();
	}
	
	@RequestMapping(value="/xml/recentsessions", method = RequestMethod.GET, produces = "application/xml")
	@ResponseBody
	public List<String> getRecentSessionsXml(HttpSession session){
		return this.getRecentSessions(session);
	}

	private boolean checkUser(long questionSessionID, String password){
		QuestionSession qs = new QuestionSession();
		qs.setID(questionSessionID);
		SQLDBHelper.fetch(qs);
		return password.equals(qs.getPassword());
	}

}
